#ifndef LEAMDATAINSTREAMHH
#define LEAMDATAINSTREAMHH
#include "leam-typedefs.hh"
#include "leam-in-stream.hh"
#include "leam-errors.hh"

namespace leam
{
    //Low level stream interface.  You provide this to the leam stream
    //These are little endian.  I expect these reads to be blocking
    //Communicating stream to application
    class LeamDataInStream : public licada::IBinaryInStream
    {
	TLength length;
	ILeamInStream* stream;
	
	LeamDataInStream( const LeamDataInStream& other );
	LeamDataInStream& operator=( const LeamDataInStream& other );
    public:
	LeamDataInStream()
	    : length( 0 ), stream( 0 ) {}
	~LeamDataInStream(){}
	void setup( TLength len, ILeamInStream* _stream) {
	    length = len;
	    stream = _stream;
	}
	void ignore( licada::uint32 numBytes ) {
	    licada::uint32 ignoreLen = std::min( length, numBytes );
	    length -= ignoreLen;
	    stream->ignore( ignoreLen );
	}
	    
	TLength getRemaining() { return length; }
	//Read either bytes or the data.  Exception is
	//thrown if over-read
	void operator >> ( licada::TDataVector& data ) {
	    checkLength( data.size() );
	    *stream >> data;
	}
	void operator >> ( licada::uint8& byte ) {
	    checkLength( 1 );
	    *stream >> byte;
	}

    private:
	void checkLength( TLength request ) {
	    if ( request > length )
		throw LeamDataStreamOverRead( length, request );
	    length -= request;
	}
    };
}
#endif
